#include "mcPoints.h"
#include <math.h>

McPoint2D::McPoint2D(void)
{
}

McPoint2D::~McPoint2D(void)
{
}

McPoint2D::McPoint2D(double x1, double y1)
{
	x = x1;
	y = y1;
}

McPoint2D::McPoint2D(const McPoint &p)
{
	x = p.X();
	y = p.Y();
}

McPoint2D McPoint2D::operator+(const McPoint2D& p)
{
	McPoint2D newp(x + p.X(), y + p.Y());
	return newp;
}

McPoint2D McPoint2D::operator-(const McPoint2D& p)
{
	McPoint2D newp(x - p.X(), y - p.Y());
	return newp;
}

McPoint2D McPoint2D::operator+=(const McPoint2D& p)
{
	McPoint2D newp(x + p.x, y + p.y);
	return newp;
}
McPoint2D McPoint2D::operator-=(const McPoint2D& p)
{
	McPoint2D newp(x - p.x, y - p.y);
	return newp;
}

McPoint2D McPoint2D::operator*(const double scale)
{
	McPoint2D newp(x * scale, y * scale);
	return newp;
}

McPoint2D McPoint2D::operator/(const double scale)
{
	McPoint2D newp(x / scale, y / scale);
	return newp;
}

McPoint2D& McPoint2D::operator=(const McPoint& p)
{
	if (this != &p)
	{
		x = p.X();
		y = p.Y();
	}

	return *this;
}

bool McPoint2D::operator==(const McPoint2D& p)
{
	return ((p.x == x) && (p.y == y));
}

ofstream & operator>>(McPoint2D &p, ofstream &strm)
{
	strm.write((char*)&(p.x), sizeof(p.x));
	strm.write((char*)&(p.y), sizeof(p.y));

	return strm;

}

ifstream & operator<<(McPoint2D &p, ifstream &strm)
{
	strm.read((char*)&(p.x), sizeof(p.x));
	strm.read((char*)&(p.y), sizeof(p.y));

	return strm;

}

double McPoint2D::Distance(const McPoint& p) const
{
	double dx = x - p.X();
	double dy = y - p.Y();
	double s = dx * dx + dy * dy;

	return (s<0 ? 0.0 : (double)sqrt(s));
}

double McPoint2D::Azimuth(const McPoint& p) const
{
	return (double)atan2(p.Y() - y, p.X() - x);
}

double McPoint2D::X() const
{
	return x;
}

double McPoint2D::GetX() const
{
	return x;
}

double McPoint2D::Y() const
{
	return y;
}

double McPoint2D::GetY() const
{
	return y;
}

double& McPoint2D::rX()
{
	return x;
}

void McPoint2D::SetX(const double x1)
{
	x = x1;
}

double& McPoint2D::rY()
{
	return y;
}

void McPoint2D::SetY(const double y1)
{
	y = y1;
}

void McPoint2D::Set(const double x1, const double y1)
{
	x = x1;
	y = y1;
}


void McPoint2D::Set(const double x1, const double y1, const double z1)
{
	x = x1;
	y = y1;
}

void McPoint2D::Get(double& x1, double& y1) const
{
	x1 = x;
	y1 = y;
}

McPoint3D::McPoint3D(void)
{
}

McPoint3D::~McPoint3D(void)
{
}

McPoint3D::McPoint3D(double x1, double y1, double z1)
{
	x = x1;
	y = y1;
	z = z1;
}

McPoint3D::McPoint3D(const McPoint& p)
{
	x = p.X();
	y = p.Y();
	z = p.Z();
}


McPoint3D McPoint3D::operator+(const McPoint3D& p)
{
	McPoint3D newp(x + p.x, y + p.y, z + p.z);
	return newp;
}

McPoint3D McPoint3D::operator-(const McPoint3D& p)
{
	McPoint3D newp(x - p.x, y - p.y, z - p.z);
	return newp;
}

McPoint3D McPoint3D::operator*(const double scale)
{
	McPoint3D newp(x*scale, y*scale, z*scale);
	return newp;
}

McPoint3D& McPoint3D::operator=(const McPoint3D& p)
{
	if (this != &p)
	{
		x = p.x;
		y = p.y;
		z = p.z;
	}
	return *this;
}

bool McPoint3D::operator==(const McPoint3D& p)
{
	return ((p.x == x) && (p.y == y) && (p.z == z));
}

void McPoint3D::Scale(const double scale)
{
	x *= scale;
	y *= scale;
	z *= scale;
}

double McPoint3D::Distance(const McPoint& p) const
{
	double dx = x - p.X();
	double dy = y - p.Y();
	double dz = z - p.Z();
	double s = dx * dx + dy * dy + dz * dz;
	return (s<0 ? 0.0 : (double)sqrt(s));
}

double McPoint3D::Z() const
{
	return z;
}

double McPoint3D::GetZ() const
{
	return z;
}

double& McPoint3D::rZ()
{
	return z;
}

void McPoint3D::SetZ(const double z1)
{
	z = z1;
}

void McPoint3D::Set(const double x1, const double y1, const double z1)
{
	x = x1;
	y = y1;
	z = z1;
}

void McPoint3D::Get(double& x1, double& y1, double& z1) const
{
	x1 = x;
	y1 = y;
	z1 = z;
}


McImagePoint::McImagePoint()
{
	x = 0;
	y = 0;
}

McImagePoint::McImagePoint(const int x1, const int y1)
{
	x = x1;
	y = y1;
}

// OPERATORS
McImagePoint McImagePoint::operator+(const McImagePoint& p) const
{
	McImagePoint newpt(x + p.X(), y + p.Y());
	return newpt;
}

McImagePoint McImagePoint::operator-(const McImagePoint& p) const
{
	McImagePoint newpt(x - p.X(), y - p.Y());
	return newpt;
}

McImagePoint& McImagePoint::operator=(const McImagePoint& p)
{
	if (this != &p)
	{
		x = p.X();
		y = p.Y();
	}
	return *this;
}

bool McImagePoint::operator==(const McImagePoint& p) const
{
	if (x == p.X() && y == p.Y())
		return true;
	else
		return false;
}

ofstream & McImagePoint::operator>>(ofstream &strm)
{
	strm.write((char*)&x, sizeof(x));
	strm.write((char*)&y, sizeof(y));

	return strm;
}

ifstream & McImagePoint::operator<<(ifstream &strm)
{
	strm.read((char*)&x, sizeof(x));
	strm.read((char*)&y, sizeof(y));

	return strm;
}

//ofstream & McImagePoint::operator>>(ofstream &strm, McImagePoint &im)
//{
//	strm.write((char*)&(im.x), sizeof(im.x));
//	strm.write((char*)&(im.y), sizeof(im.y));
//
//	return strm;
//
//}
//
//ifstream & McImagePoint::operator << (ifstream &strm, McImagePoint &im)
//{
//	strm.read((char*)&(im.x), sizeof(im.x));
//	strm.read((char*)&(im.y), sizeof(im.y));
//
//	return strm;
//
//}

void McImagePoint::Set(const McPoint2D pt)
{
	int temp1, temp2;

	temp1 = (int)ceil(pt.X());
	temp2 = (int)floor(pt.X());
	if (fabs(pt.X() - temp1) < fabs(pt.X() - temp2))
		x = temp1;
	else
		x = temp2;

	temp1 = (int)ceil(pt.Y());
	temp2 = (int)floor(pt.Y());
	if (fabs(pt.Y() - temp1) < fabs(pt.Y() - temp2))
		y = temp1;
	else
		y = temp2;
}
